﻿
Imports System.IO

Namespace storageJobConsumerInternal
    Public Class fcesdiskslice_atom(Of READONLY_CLUSTERID As _boolean)
        Inherits atom

        Public Shared ReadOnly metalen As Int32 = 0
        Private Shared ReadOnly clusterId_readonly As Boolean = False

        Private _clusterId As Int64 = npos
        Public Property clusterId() As Int64
            Get
                assert(_clusterId <> npos)
                Return _clusterId
            End Get
            Set(ByVal value As Int64)
                assert(value <> npos)
                If clusterId_readonly Then
                    assert(_clusterId = npos)
                End If
                _clusterId = value
            End Set
        End Property

        Shared Sub New()
            metalen = sizeof(Of Int64)()
            clusterId_readonly = +(alloc(Of READONLY_CLUSTERID)())
        End Sub

        Public Sub New(ByVal start As UInt64, ByVal metaStart As UInt64, ByVal metaLength As UInt64)
            MyBase.New(start, metaStart, metaLength)
        End Sub

        Public Overrides Function read(ByVal meta As bytes) As Boolean
            Dim i As Int64 = 0
            Return meta.size() = metalen AndAlso
                   convertor.toint64(meta, i) AndAlso
                   i <> npos AndAlso
                   true_(Sub()
                             clusterId() = i
                         End Sub)
        End Function
    End Class

    Public MustInherit Class fcesdiskslice(Of CLUSTERID_READONLY As _boolean)
        Inherits diskslice(Of fcesdiskslice_atom(Of CLUSTERID_READONLY))

        Public Sub New()
            MyBase.New(True)
        End Sub

        Protected MustOverride Function fcesfolder() As String
        Protected MustOverride Function open_fces(ByVal file As String, ByVal buffSize As Int32) As Boolean
        Protected MustOverride Function close_fces() As Boolean
        Protected MustOverride Overrides Function modify(ByVal atom As fcesdiskslice_atom(Of CLUSTERID_READONLY),
                                                         ByVal buff As bytes) As eventComb
        Protected MustOverride Overrides Function append(ByVal atom As fcesdiskslice_atom(Of CLUSTERID_READONLY),
                                                         ByVal buff As bytes) As eventComb
        Protected MustOverride Overrides Function write(ByVal atom As fcesdiskslice_atom(Of CLUSTERID_READONLY),
                                                        ByVal buff As bytes) As eventComb
        Protected MustOverride Overrides Function sizeof(ByVal atom As fcesdiskslice_atom(Of CLUSTERID_READONLY)) _
                                                        As Int64
        Protected MustOverride Overrides Sub flush()

        Private _fcesBuffSize As Int32 = npos
        Private Property fcesBuffSize As Int32
            Get
                assert(_fcesBuffSize <> npos)
                Return _fcesBuffSize
            End Get
            Set(ByVal value As Int32)
                assert(_fcesBuffSize = npos)
                assert(value <> npos)
                _fcesBuffSize = value
            End Set
        End Property

        Protected NotOverridable Overrides Function atom_ctor(ByVal start As UInt64,
                                                              ByVal metaStart As UInt64,
                                                              ByVal metaLength As UInt64) _
                                                             As fcesdiskslice_atom(Of CLUSTERID_READONLY)
            Return New fcesdiskslice_atom(Of CLUSTERID_READONLY)(start, metaStart, metaLength)
        End Function

        Protected NotOverridable Overrides Function metaLength(ByVal buff As bytes) As UInt64
            Return fcesdiskslice_atom(Of CLUSTERID_READONLY).metalen
        End Function

        Protected NotOverridable Overrides Function after_open() As Boolean
            Return open_fces(fcesDataFileFullpath(), fcesBuffSize()) AndAlso MyBase.after_open()
        End Function

        Protected NotOverridable Overrides Function after_close() As Boolean
            Return close_fces() AndAlso MyBase.after_close()
        End Function

        Protected NotOverridable Overrides Function after_create() As Boolean
            Dim rtn As Boolean = True
            If File.Exists(fcesDataFileFullpath()) Then
                rtn = delete_fcesDataFile()
            End If
            Return rtn And MyBase.after_create()
        End Function

        Protected NotOverridable Overrides Function retire() As Boolean
            Return delete_fcesDataFile()
        End Function

        Private Function delete_fcesDataFile() As Boolean
            Try
                File.Delete(fcesDataFileFullpath())
                Return True
            Catch ex As Exception
                raiseError(errorHandle.errorType.exclamation,
                           "failed to delete fces data file ", fcesDataFileFullpath())
                Return False
            End Try
        End Function

        Private _fcesdatapath As String = Nothing
        Private Function fcesdatapath() As String
            If _fcesdatapath Is Nothing Then
                _fcesdatapath = combinepath(datafullpath(), fcesfolder())
                createFcesDataPath()
            End If
            Return _fcesdatapath
        End Function

        Private _fcesDataFileFullpath As String = Nothing
        Private Function fcesDataFileFullpath() As String
            If _fcesDataFileFullpath Is Nothing Then
                _fcesDataFileFullpath = combinepath(fcesdatapath(), indexfile())
            End If
            Return _fcesDataFileFullpath
        End Function

        Private Function createFcesDataPath() As Boolean
            Return createDirectory(fcesdatapath())
        End Function

        Private Shared Function initialFcesBuffSize(ByVal name As String,
                                                    ByVal config As configParser,
                                                    ByVal c As fcesdiskslice(Of CLUSTERID_READONLY)) As Boolean
            Const defaultValue As UInt64 = (1 << 18)    '262144
            Dim buffsize As UInt64 = 0
            Dim str As String = Nothing
            If Not config.getparameter(name, "fcesBuffSize", str, defaultValue.ToString()) OrElse
               Not convertor.touint64(str, buffsize) OrElse
               buffsize = 0 Then
                buffsize = defaultValue
            End If
            c.fcesBuffSize() = buffsize
            Return True
        End Function

        Protected Shared Shadows Function initial(ByVal name As String,
                                                  ByVal config As configParser,
                                                  ByVal c As fcesdiskslice(Of CLUSTERID_READONLY)) As Boolean
            Return initialFcesBuffSize(name, config, c) AndAlso
                   diskslice(Of fcesdiskslice_atom(Of CLUSTERID_READONLY)).initial(name, config, c)
        End Function
    End Class
End Namespace
